/**
 * 
 */
package org.intelligentsia.artifacts.repository;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.intelligentsia.utilities.FileUtils;
import org.intelligentsia.utilities.StringUtils;

/**
 * @author geronimo
 * 
 */
public class FileRepository {

	private Repository	repository;
	private FileLocator	locator;

	/**
	 * Build a new instance of <code>FileRepository</code>
	 * 
	 * @throws MalformedURLException
	 */
	public FileRepository(Repository repository) throws MalformedURLException {
		this.repository = repository;
		initialize();
	}

	private void initialize() throws MalformedURLException, IllegalArgumentException {
		URL rootUrl = new URL(repository.getUrl());
		if (!"file".equals(rootUrl.getProtocol())) {
			throw new IllegalArgumentException("url " + repository.getUrl() + " not using file protocol");
		}
		locator = new FileLocator(new File(rootUrl.getFile()));
	}

	public void put(String resource, File source) throws IllegalArgumentException, IOException {
		FileUtils.copy(source, locator.resolve(resource), true);
	}

	public File get(String resource) {
		return locator.resolve(resource);
	}

	public boolean exists(String resource) {
		File destination = locator.resolve(resource);
		if (resource.endsWith("/")) {
			return destination.isDirectory();
		}
		return destination.exists();
	}

	public List<File> list(String resource) {
		File destination = locator.resolve(resource);
		if (!destination.isDirectory()) {
			return Collections.emptyList();
		}
		return Arrays.asList(destination.listFiles());
	}

	/**
	 * Inner locator.
	 * 
	 * @author geronimo
	 * 
	 */
	private class FileLocator implements Locator<File> {
		private File	root;

		/**
		 * Build a new instance of <code>FileLocator</code>
		 * 
		 * @param root
		 */
		public FileLocator(File root) throws IllegalArgumentException {
			super();
			this.root = root;
			if (!root.exists()) {
				root.mkdirs();
			}
			if (!root.isDirectory()) {
				throw new IllegalArgumentException("Root " + root.getName() + " is not a directory");
			}
			if (!root.canRead()) {
				throw new IllegalArgumentException("Root " + root.getName() + " cannot be read");
			}
		}

		@Override
		public File getRoot() {
			return root;
		}

		@Override
		public File resolve(String target) {
			String destination = StringUtils.replace(target, "\\", "/");
			File path = null;
			if (destination.equals(".")) {
				path = root;
			} else {
				path = new File(root, destination);
			}
			return path;
		}

	}
 
}
